<script setup lang="ts" name="FolderForm">
import { storeToRefs } from 'pinia'
import { useAppStoreWithOut } from '@/store/modules/app'
import { FolderApi, FolderType } from '@/api/infra/resource/library'
import { defaultProps } from '@/utils/tree'
import { ElTree } from 'element-plus'
const appStore = useAppStoreWithOut()
const { systemConfig } = storeToRefs(appStore)

const emit = defineEmits(['success'])
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗

defineProps({
  folderList: { type: Array as any }
})
const visible = ref(false) // 弹窗的是否展示
const title = ref('') // 弹窗的标题
const formLoading = ref(false) // 表单的加载中：1）修改时的数据加载；2）提交的按钮禁用
const formType = ref('') // 表单的类型：create - 新增；update - 修改； rename - 重命名； move - 移动到
const formData = ref<FolderType>({
  id: undefined,
  parentId: 0,
  name: '',
  sort: 0
})
const formRules = reactive({
  name: [{ required: true, message: t('infra.resource.library.folder.rules', 'name'), trigger: 'blur' }],
  sort: [{ required: true, message: t('infra.resource.library.folder.rules', 'sort'), trigger: 'blur' }],
})
const formRef = ref() // 表单 Ref
const treeRef = ref<InstanceType<typeof ElTree>>()
const checkedKey = ref(0) // 已选中的节点 id
const collapseKeys = ref<number[]>([]) // 已折叠的节点 id 数组

// 显示弹窗
const open = async (type: string, data?: FolderType) => {
  visible.value = true
  title.value = t('action', type)
  formType.value = type
  resetForm()
  // 修改时，设置数据
  if (data) {
    formLoading.value = true
    try {
      if (type === 'create') {
        if (data.id !== 0) {
          formData.value.parentId = data.id
        }
      } else {
        formData.value = data
      }
    } finally {
      formLoading.value = false
    }
  }
}

// 子组件将方法暴露给父组件
defineExpose({ open })

const submitForm = async () => {
  // 校验表单
  if (!formRef) return
  const valid = await formRef.value.validate()
  if (!valid) return
  // 提交请求
  formLoading.value = true
  try {
    const data = formData.value as unknown as FolderType
    if (formType.value === 'create') {
      await FolderApi.create(data)
      message.success(t('message', 'createSuccess'))
    } else if (formType.value === 'rename') {
      await FolderApi.rename(data)
      message.success(t('message', 'updateSuccess'))
    } else if (formType.value === 'move') {
      await FolderApi.move(data)
      message.success(t('message', 'updateSuccess'))
    } else {
      await FolderApi.update(data)
      message.success(t('message', 'updateSuccess'))
    }
    visible.value = false
    // 发送操作成功的事件
    emit('success')
  } finally {
    formLoading.value = false
  }
}

/** 重置表单 */
const resetForm = () => {
  formData.value = {
    id: undefined,
    parentId: 0,
    name: '',
    sort: 0
  }
  formRef.value?.resetFields()
}

/** 基于名字过滤 */
const filterNode = (name: string, data: Tree) => {
  if (!name) return true
  if (!data.name) return false
  return data.name.includes(name)
}


/** 处理文件夹被点击 */
const handleNodeClick = async (row: { [key: string]: any }) => {
  treeRef.value!.setChecked(checkedKey.value, false, false)
  checkedKey.value = row.id
  treeRef.value!.setChecked(checkedKey.value, true, false)
}

/** 处理文件夹节点被展开 */
const handleNodeExpand = async row => {
  const index = collapseKeys.value.findIndex(item => item === row.id)
  if (index !== -1) {
    collapseKeys.value.splice(index, 1)
  }
}

/** 处理文件夹节点被折叠 */
const handleNodeCollapse = async row => {
  collapseKeys.value.push(row.id)
}

/** 处理树形结构折叠时的线条显示隐藏状态 */
const isCollapse = id => {
  return collapseKeys.value.some(item => item === id)
}
</script>

<template>
  <Dialog v-model="visible" :title="title" width="700px">
    <ElForm ref="formRef" v-loading="formLoading && systemConfig.loadingType === 'module'" :model="formData" :rules="formRules" label-width="auto">
      <ElFormItem :label="t('infra.resource.library.folder', 'parentId')">
        <ElTreeSelect
          ref="treeRef"
          v-model="formData.parentId"
          class="tree-level"
          :data="folderList"
          :props="defaultProps"
          node-key="id"
          filterable
          :disabled="formType !== 'create' && formType !== 'move'"
          default-expand-all
          :expand-on-click-node="false"
          :filter-node-method="filterNode"
          :highlight-current="true"
          :check-on-click-node="true"
          check-strictly
          @node-click="handleNodeClick"
          @node-expand="handleNodeExpand"
          @node-collapse="handleNodeCollapse">
          <template #default="{ node, data }">
            <span class="item-tree-node">
              <span>{{ node.label }}</span>
              <template v-for="item in data.level">
                <span v-if="!data.hideLine.includes(item)" :key="item" :class="['item-tree-node-line-vertical', data.isLast && item == data.level ? 'is-last' : '', data.isFirst && data.level === 1 ? 'is-first' : '']" :style="{ left: 18 * (item - 1) + 12 + 'px' }" />
              </template>
              <span v-if="!data.isLeaf && !isCollapse(data.id)" class="item-tree-node-line-vertical is-first" :style="{ left: 18 * (data.level) + 12 + 'px' }" />
              <span class="item-tree-node-line-horizontal" :style="{ left: 18 * (data.level - 1) + 12 + 'px' }" />
            </span>
          </template>
        </ElTreeSelect>
      </ElFormItem>
      <ElFormItem :label="t('infra.resource.library.folder', 'name')" prop="name">
        <ElInput v-model="formData.name" :disabled="formType !== 'create' && formType !== 'rename'" clearable maxlength="20" show-word-limit :placeholder="t('infra.resource.library.folder.placeholder', 'name')" />
      </ElFormItem>
      <ElFormItem :label="t('common', 'sort')" prop="sort">
        <el-input-number v-model="formData.sort" :disabled="formType !== 'create' && formType !== 'move'" clearable />
      </ElFormItem>
    </ElForm>
    <template #footer>
      <el-button @click="visible = false">{{ t('action', 'cancel') }}</el-button>
      <el-button :disabled="formLoading" type="primary" @click="submitForm">{{ t('action', 'confirm') }}</el-button>
    </template>
  </Dialog>
</template>

<style scoped lang="scss">
.el-form{
  padding: 40px 100px;
}
</style>
